﻿using System;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.LoadTesting;

namespace WebAndLoadTestPluginsAndRules.LoadTestPlugins
{
    /// <summary>
    /// Load pattern to step up and then back down. For the step up, use the step load pattern in your scenario.
    /// </summary>
    [Serializable()]
    public class StepUpAndDownLoadProfile : LoadTestStepLoadProfile
    {
        public StepUpAndDownLoadProfile(int runDuration)
        {
            InitialUserCount = 10;
            StepUserCount = 10;
            StepDuration = 10;
            StartStepDownAtRunOffset = runDuration;
            m_runDuration = runDuration;
        }        

        // ******************************************************************
        public override int GetLoad(int elapsed)
        {
            if (elapsed < StartStepDownAtRunOffset)
            {
                m_lastStepUpCount = base.GetLoad(elapsed);
                return m_lastStepUpCount;
            }
            else
            {
                long currentUserCount = m_lastStepUpCount - (StepDownUserCount * ((elapsed - StartStepDownAtRunOffset) / StepDownStepDuration));
                return (int)Math.Max(Math.Max(currentUserCount, 0), MinUserCount);
            }           
        }

        public override void Validate()
        {
            base.Validate();
        }

        public int StepDownUserCount {get; set;}
        public int StepDownStepDuration { get; set; }
        public int StartStepDownAtRunOffset { get; set; }

        // ******************************************************************
        // Private members
        // ******************************************************************         
        private int m_runDuration;        
        private int m_lastStepUpCount;
    }

    /// <summary>
    /// 
    /// </summary>
    public class StepUpAndDownLoadTestPlugin : ILoadTestPlugin
    {
        #region ILoadTestPlugin Members
        public void Initialize(LoadTest loadTest)
        {
            StepUpAndDownLoadProfile p = new StepUpAndDownLoadProfile(loadTest.RunSettings.RunDuration);
            p.InitialUserCount = InitialUserCount;
            p.MaxUserCount = MaxUserCount;
            p.MinUserCount = MinUserCount;
            p.StepUserCount = StepUpStepUserCount;
            p.StepDuration = StepUpStepDuration;
            p.StepRampTime = StepRampTime;
            p.StartStepDownAtRunOffset = StartStepDownAtRunOffset;
            p.StepDownStepDuration = StepDownStepDuration;
            p.StepDownUserCount = StepDownStepUserCount;

            // Todo: Add a list of scenarios string property to control which scenarios to apply this to.
            loadTest.Scenarios[0].LoadProfile = p;
        }
        #endregion

        public int InitialUserCount = 20;
        public int MaxUserCount = 100;
        public int MinUserCount = 5;
        public int StepUpStepUserCount = 5;
        public int StepUpStepDuration = 10;
        public int StepRampTime = 5;
        public int StartStepDownAtRunOffset = 480;
        public int StepDownStepDuration = 10;
        public int StepDownStepUserCount = 10;
    }
}
